<?php
	require_once("Service.php");
	require_once("Database.php");
	require_once("vo/UserVO.php");
	require_once("vo/AvatarVO.php");
	require_once("vo/ThemeVO.php");
	require_once("vo/GroupVO.php");
	
	/**
	 * Class which handles all core system related queries.
	 */
	class CoreSystemService extends Service {
		
		var $conn;
		
		/** The constructor of this object. */
		function __construct() {
			
			parent::__construct();
			$this->conn = new Database();
		}
		
		/**
		 * Attempts to log in a user using a email and password combination.
		 * @param $email The email address of the user.
		 * @param $password The password of the user.
		 * @return The session details of the user, otherwise null.
		 */
		function loginUser($email, $password) {
			
			$query = Database::buildQuery("
				SELECT userUID
				FROM Users
				WHERE email = ?
				AND password = ?
				AND isArchived = 0
			", $email, md5($password));
			$qryUserCheck = $this->conn->execute($query);
			
			if(mysql_num_rows($qryUserCheck) == 1) {
			
				$recUserCheck = mysql_fetch_assoc($qryUserCheck);
				return $this->createUserSession($recUserCheck["userUID"]);
				
			} else {
				
				return null;
			}
		}
		
		/**
		 * Attempts to register a user on the system.
		 * @param $firstName The first name of the user.
		 * @param $lastName The last name of the user.
		 * @param $email The email address of the user.
		 * @param $password The password of the user.
		 * @param $phoneNumber The phone number of the user.
		 * @param $description A short biographic description of the user.
		 * @param $gender The gender of the user.
		 * @param $dateOfBirth The birth date of the user.
		 * @param $location The country/city where the user is from.
		 * @param $occupation The job title of the user.
		 * @param $institution The company the user works for.
		 * @return The session details of the user, otherwise null.
		 */
		function registerUser(
			$firstName,
			$lastName,
			$email,
			$password,
			$phoneNumber,
			$description,
			$gender,
			$dateOfBirth,
			$location,
			$occupation,
			$institution) {
			
			$query = Database::buildQuery("
				SELECT userUID
				FROM Users
				WHERE email = ?
			", $email);
			$qryUserCheck = $this->conn->execute($query);
			
			if(mysql_num_rows($qryUserCheck) == 0) {
				
				$userUID = $this->conn->generateUID(); 
				
				$query = Database::buildQuery("
					INSERT INTO Users(
						userUID,
						firstName,
						lastName,
						email,
						password,
						phoneNumber,
						description,
						gender,
						dateOfBirth,
						location,
						occupation,
						institution,
						avatarUID,
						themeUID
					) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
				", $userUID, $firstName, $lastName, $email, md5($password), $phoneNumber, $description, $gender, $dateOfBirth, $location, $occupation, $institution, "2", "9");
				$this->conn->execute($query);
				
				return $this->createUserSession($userUID);
				
			} else {
				
				return null;
			}
		}
		
		/**
		 * Terminates a user session.
		 * @param $sessionID The id of the session to terminate.
		 */
		function logoutUser($sessionID) {
			
			$this->terminateSession($sessionID);
		}
		
		/**
		 * Creates a new user session.
		 * @param $userUID The user who is logging in.
		 * @return An object containing the user's session data.
		 */
		function createUserSession($userUID) {
			
			$query = Database::buildQuery("
				SELECT
					Users.userUID,
					Users.firstName,
					Users.lastName,
					Users.email,
					Users.phoneNumber,
					Users.isAdministrator,
					Users.description,
					Users.gender,
					DATE_FORMAT(dateOfBirth, '%Y/%m/%d') AS dateOfBirth,
					Users.location,
					Users.occupation,
					Users.institution,
					Users.status,
					Avatars.avatarUID,
					Avatars.avatarName,
					Avatars.description as avatarDesc,
					Themes.themeUID,
					Themes.themeName,
					Themes.description as themeDesc
				FROM Users
				INNER JOIN Avatars
					ON Avatars.avatarUID = Users.avatarUID
				INNER JOIN Themes
					ON Themes.themeUID = Users.themeUID
				WHERE Users.userUID = ?
			", $userUID);
			$qryUserData = $this->conn->execute($query);
			
			$recUserData = mysql_fetch_assoc($qryUserData);
			
			$result = array();
			$result["sessionID"] = $this->allocateSession($recUserData["userUID"]);
			$result["userData"] = UserVO::mapObject($recUserData);
			$result["avatar"] = AvatarVO::mapObject($recUserData);
			$result["theme"] = ThemeVO::mapObject($recUserData);
			
			$result["avatar"]->description = $recUserData["avatarDesc"];
			$result["theme"]->description = $recUserData["themeDesc"];
			
			// get a list of the user's groups
			$query = Database::buildQuery("
				SELECT
					Groups.groupUID,
					Groups.groupName,
					Groups.description,
					Groups.logoURL,
					Groups.chatURL,
					UserGroups.isManager
				FROM UserGroups
				INNER JOIN Groups
					ON Groups.groupUID = UserGroups.groupUID
				WHERE UserGroups.userUID = ?
				AND UserGroups.isBanned = 0
				AND Groups.isArchived = 0
			", $recUserData["userUID"]);
			$qryUserGroups = $this->conn->execute($query);
			
			$groups = array();
			while($recUserGroups = mysql_fetch_assoc($qryUserGroups)) {
				$groups[] = GroupVO::mapObject($recUserGroups);
			}
			$result["groups"] = $groups;
			
			// store the login
			$query = Database::buildQuery("
				INSERT INTO Logins(
					loginDate,
					userUID
				) VALUES (?, ?)
			", date("Y-m-d H:i:s"), $userUID);
			$this->conn->execute($query);
			
			return $result;
		}
		
		/**
		 * Saves changes made to a users details.
		 * @param $sessionID The sessionID of the user calling this function.
		 * @param $userUID The user who's details to edit.
		 * @param $firstName The first name of the user.
		 * @param $lastName The last name of the user.
		 * @param $email The email address of the user.
		 * @param $password The password of the user.
		 * @param $phoneNumber The phone number of the user.
		 * @param $description A short biographic description of the user.
		 * @param $gender The gender of the user.
		 * @param $dateOfBirth The birth date of the user.
		 * @param $location The country/city where the user is from.
		 * @param $occupation The job title of the user.
		 * @param $institution The company the user works for.
		 * @param $avatarUID The avatar the user has chosen.
		 * @param $themeUID The theme the user has chosen.
		 * @return True if successful, otherwise false.
		 */
		function saveUserSettings(
			$sessionID,
			$userUID,
			$firstName,
			$lastName,
			$email,
			$password,
			$phoneNumber,
			$description,
			$gender,
			$dateOfBirth,
			$location,
			$occupation,
			$institution,
			$avatarUID,
			$themeUID) {
				
			$this->validateSession($sessionID);
			
			// check if there are already users with the supplied email address
			$query = Database::buildQuery("
				SELECT userUID
				FROM Users
				WHERE email = ?
				AND userUID <> ?
			", $email, $userUID);
			$qryUserCheck = $this->conn->execute($query);
			
			if(mysql_num_rows($qryUserCheck) == 0) {
				
				$query = Database::buildQuery("
					UPDATE Users
					SET
						firstName = ?,
						lastName = ?,
						email = ?,
						phoneNumber = ?,
						description = ?,
						gender = ?,
						dateOfBirth = ?,
						location = ?,
						occupation = ?,
						institution = ?,
						avatarUID = ?,
						themeUID = ?
					WHERE userUID = ?
				", $firstName, $lastName, $email, $phoneNumber, $description, $gender, $dateOfBirth, $location, $occupation, $institution, $avatarUID, $themeUID, $userUID);
				$this->conn->execute($query);
				
				if($password != "") {
					
					$query = Database::buildQuery("
						UPDATE Users
						SET password = ?
						WHERE userUID = ?
					", md5($password), $userUID);
					$this->conn->execute($query);
				}
				
				return true;
				
			} else {
				
				return false;
			}
		}
		
		/**
		 * Finds a list of avatars the user may choose from.
		 * @param $sessionID The sessionID of the user calling this function.
		 * @return An array of avatars.
		 */
		function getAvatarList($sessionID) {
			
			$this->validateSession($sessionID);
			
			// get the avatars the user may choose from
			$qryAvatars = $this->conn->execute("
				SELECT
					avatarUID,
					avatarName,
					description
				FROM Avatars
			");
			
			$avatars = array();
			while($recAvatars = mysql_fetch_assoc($qryAvatars)) {
				$avatars[] = AvatarVO::mapObject($recAvatars);
			}
			
			return $avatars;
		}
		
		/**
		 * Finds a list of themes the user may choose from.
		 * @param $sessionID The sessionID of the user calling this function.
		 * @return An array of themes.
		 */
		function getThemeList($sessionID) {
			
			$this->validateSession($sessionID);
			
			// get the themes the user may choose from
			$qryThemes = $this->conn->execute("
				SELECT
					themeUID,
					themeName,
					description
				FROM Themes
			");
			
			$theme = array();
			while($recThemes = mysql_fetch_assoc($qryThemes)) {
				$theme[] = ThemeVO::mapObject($recThemes);
			}
			
			return $theme;
		}
	}
?>